home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Softshoe / Lisa's Portable Parts / BitArray / BitArrayBase.cp < prev    next >
Encoding:
Text File  |  2000-06-23  |  4.7 KB  |  240 lines

  1. // BitArrayBase.cp
  2.  
  3. #ifndef BitArrayBase_h
  4. #include "BitArrayBase.h"
  5. #endif
  6. #ifndef MinMax_h
  7. #include "MinMax.h"
  8. #endif
  9. #ifndef Bits_h
  10. #include "Bits.h"
  11. #endif
  12.  
  13. BitArrayBase::BitArrayBase( uint32 *theBits,
  14.                                      uint32 theLength )
  15.   : bits( theBits ),
  16.      length( theLength ),
  17.      units( (theLength + unitLength - 1) / unitLength ),
  18.      end( bits + (theLength + unitLength - 1) / unitLength ),
  19.      lastUnitMask( (theLength % unitLength == 0)
  20.                          ? ~0L
  21.                          : (1L << (theLength % unitLength)) - 1 )
  22.   {}
  23.     
  24. BitArrayBase::BitArrayBase( uint32 *theBits,
  25.                                      uint32 theLength,
  26.                                      bool initialValue )
  27.   : bits( theBits ),
  28.      length( theLength ),
  29.      units( (theLength + unitLength - 1) / unitLength ),
  30.      end( bits + (theLength + unitLength - 1) / unitLength ),
  31.      lastUnitMask( (theLength % unitLength == 0)
  32.                          ? ~0L
  33.                          : (1L << (theLength % unitLength)) - 1 )
  34.   {
  35.     SetAll( initialValue );
  36.     if ( initialValue )
  37.         SetAll();
  38.      else
  39.         ClearAll();
  40.   }
  41.  
  42. bool BitArrayBase::operator[]( uint32 i ) const
  43.   {
  44.     Assert( i < length );
  45.     return ( bits[ i/unitLength ] & 1L << ( i % unitLength ) ) != 0;
  46.   }
  47.  
  48. BitReference BitArrayBase::operator[]( uint32 i )
  49.   {
  50.     Assert( i < length );
  51.     return BitReference( bits[ i/unitLength ], i % unitLength );
  52.   }
  53.  
  54. void BitArrayBase::SetAll( bool value )
  55.   {
  56.     if ( value )
  57.         SetAll();
  58.      else
  59.         ClearAll();
  60.   }
  61.  
  62. void BitArrayBase::SetAll()
  63.   {
  64.     for ( Unit *p = bits; p < end; p++ )
  65.         *p = ~0L;
  66.   }
  67.  
  68. void BitArrayBase::ClearAll()
  69.   {
  70.     for ( Unit *p = bits; p < end; p++ )
  71.         *p = 0;
  72.   }
  73.  
  74. void BitArrayBase::ChangeAll()
  75.   {
  76.     for ( Unit *p = bits; p < end; p++ )
  77.         *p = ~*p;
  78.   }
  79.  
  80. void BitArrayBase::operator=( const BitArrayBase& r )
  81.   {
  82.     Assert( length == r.length );
  83.     
  84.     if ( this == &r )
  85.         return;
  86.     
  87.     Unit *p = bits;
  88.     const Unit *q = r.bits;
  89.     
  90.     while ( p < end )
  91.         *p++ = *q++;
  92.   }
  93.  
  94. void BitArrayBase::operator&=( const BitArrayBase& r )
  95.   {
  96.     Assert( length == r.length );
  97.     
  98.     if ( this == &r )
  99.         return;
  100.     
  101.     Unit *p = bits;
  102.     const Unit *q = r.bits;
  103.     
  104.     while ( p < end )
  105.         *p++ &= *q++;
  106.   }
  107.  
  108. void BitArrayBase::operator|=( const BitArrayBase& r )
  109.   {
  110.     Assert( length == r.length );
  111.     
  112.     if ( this == &r )
  113.         return;
  114.     
  115.     Unit *p = bits;
  116.     const Unit *q = r.bits;
  117.     
  118.     while ( p < end )
  119.         *p++ |= *q++;
  120.   }
  121.  
  122. void BitArrayBase::operator^=( const BitArrayBase& r )
  123.   {
  124.     Assert( length == r.length );
  125.     
  126.     if ( this == &r )
  127.       {
  128.         ClearAll();
  129.         return;
  130.       }
  131.     
  132.     Unit *p = bits;
  133.     const Unit *q = r.bits;
  134.     
  135.     while ( p < end )
  136.         *p++ ^= *q++;
  137.   }
  138.  
  139. bool BitArrayBase::operator==( const BitArrayBase& r ) const
  140.   {
  141.     Assert( length == r.length );
  142.  
  143.     if ( this == &r )
  144.         return true;
  145.     
  146.     const Unit *last = end - 1;
  147.  
  148.     Unit *p = bits;
  149.     const Unit *q = r.bits;
  150.     while ( p < last )
  151.         if ( *p++ != *q++ )
  152.             return false;
  153.     
  154.     return ( (*p ^ *q) & lastUnitMask ) != 0;
  155.   }
  156.  
  157. uint32 BitArrayBase::FirstZero( uint32 start ) const
  158.   {
  159.     Assert( start <= length );
  160.     
  161.     Unit *p = bits + start / unitLength;
  162.     if ( p >= end )
  163.         return length;
  164.     
  165.     Unit skip = ( 1L << (start % unitLength) ) - 1;
  166.     Unit firstUnit = *p | skip;
  167.     if ( firstUnit != ~0L )
  168.       {
  169.         uint32 result = (p - bits) * unitLength + Bits::FirstZero( firstUnit );
  170.         return Min( result, length );
  171.       }
  172.     
  173.     const Unit *last = end - 1;
  174.     for ( p++; p < last; p++ )
  175.         if ( *p != ~0L )
  176.             return (p - bits) * unitLength + Bits::FirstZero( *p );
  177.     
  178.     return (p - bits) * unitLength + Bits::FirstZero( *p & lastUnitMask );
  179.   }
  180.  
  181. uint32 BitArrayBase::FirstOne( uint32 start ) const
  182.   {
  183.     Assert( start <= length );
  184.     
  185.     Unit *p = bits + start / unitLength;
  186.     if ( p >= end )
  187.         return length;
  188.     
  189.     Unit skip = ( 1L << (start % unitLength) ) - 1;
  190.     Unit firstUnit = *p & ~skip;
  191.     if ( firstUnit != 0 )
  192.       {
  193.         uint32 result = (p - bits) * unitLength + Bits::FirstOne( firstUnit );
  194.         return Min( result, length );
  195.       }
  196.     
  197.     const Unit *last = end - 1;
  198.     for ( p++; p < last; p++ )
  199.         if ( *p != 0 )
  200.             return (p - bits) * unitLength + Bits::FirstOne( *p );
  201.     
  202.     return (p - bits) * unitLength + Bits::FirstOne( *p | ~lastUnitMask );
  203.   }
  204.  
  205. uint32 BitArrayBase::LastZero( uint32 start ) const
  206.   {
  207.     Assert( start <= length );
  208.     
  209.     Unit *p = bits + start / unitLength;
  210.  
  211.     Unit skip = ( 1L << (start % unitLength) ) - 1;
  212.     Unit firstUnit = *p | ~skip;
  213.     if ( firstUnit != ~0L )
  214.         return (p - bits) * unitLength + Bits::LastZero( firstUnit );
  215.  
  216.     for ( p--; p >= bits; p-- )
  217.         if ( *p != ~0L )
  218.             return (p - bits) * unitLength + Bits::LastZero( *p );
  219.     
  220.     return length;
  221.   }
  222.  
  223. uint32 BitArrayBase::LastOne( uint32 start ) const
  224.   {
  225.     Assert( start <= length );
  226.     
  227.     Unit *p = bits + start / unitLength;
  228.  
  229.     Unit skip = ( 1L << (start % unitLength) ) - 1;
  230.     Unit firstUnit = *p & skip;
  231.     if ( firstUnit != 0 )
  232.         return (p - bits) * unitLength + Bits::LastOne( firstUnit );
  233.  
  234.     for ( p--; p >= bits; p-- )
  235.         if ( *p != 0 )
  236.             return (p - bits) * unitLength + Bits::LastOne( *p );
  237.     
  238.     return length;
  239.   }
  240.